package com.aop.demo.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author H
 * @date 2022/10/20
 */
@Aspect
@Component
@Order(6)
public class AopAnnotationAspect1 {

    /**
     * 这里的路径填写自定义注解的全路径
     */
    @Pointcut("@annotation(com.aop.demo.aop.AopAnnotation1)")
    public void testAnnotation() {
    }

    /**
     * 在方法执行之前执行
     * @param joinPoint
     */
    @Before("testAnnotation()")
    public void beforeCut(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        System.out.println("[Before AopAnnotation1] 注解方式aop开始拦截，当前拦截的方法名:" + method.getName());
    }

    /**
     * 在方法执行之后执行
     * @param joinPoint
     */
    @After("testAnnotation()")
    public void afterCut(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        System.out.println("[After AopAnnotation1] 注解方式aop执行的方法：" + method.getName() + "执行完了");
    }

    /**
     * 围绕方法的执行
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("testAnnotation()")
    public Object aroundCut(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("[Around AopAnnotation1] 开始进入环绕通知");
        // 获取注解参数
        // System.out.println("=========获取注解参数开始========");
        // MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        // Method method = methodSignature.getMethod();
        // AopAnnotation annotation = method.getAnnotation(AopAnnotation.class);
        // System.out.println(annotation.value());
        // System.out.println(annotation.type());
        // System.out.println("=========获取注解参数完成========");

        Object proceed = joinPoint.proceed();
        System.out.println("[Around AopAnnotation1] 准备退出环绕");
        return proceed;
    }

    /**
     * 在方法返回结果之后执行
     * @param joinPoint
     * @param result
     */
    @AfterReturning(value = "testAnnotation()", returning = "result")
    public void afterReturn(JoinPoint joinPoint, Object result) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        System.out.println("[AfterReturning AopAnnotation1] 注解方式AOP拦截的方式执行成功，进入返回通知拦截，方法名为：" + method.getName() + "，返回结果为：" + result.toString());
    }

    /**
     * 在方法抛出异常后执行
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(value = "testAnnotation()", throwing = "e")
    public void afterThrow(JoinPoint joinPoint, Exception e) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        System.out.println("[AfterThrowing AopAnnotation1] 注解方式aop进入方法异常拦截，方法名为："+  method.getName() + ",异常信息为：" + e.getMessage());
    }

}
